﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using VDataAdapter.BlockingQueue;


namespace VDataAdapter
{
    public enum MessageFlagSequeue
    {
        NULL,
        BEGIN,
        END,
        END_RECOVERY
    };

    /// <summary>
    /// Helper class to:
    /// - Map Vdata Flag to String
    /// - Convert back & forth
    /// </summary>
    static class VDataFlag
    {
        public static string GetFlag(MessageFlagSequeue flag)
        {
            if (flag == MessageFlagSequeue.BEGIN)
                return "BEGIN#_#_";
            else
                if (flag == MessageFlagSequeue.END)
                    return "END#_#_";
                else
                    if(flag == MessageFlagSequeue.END_RECOVERY)
                        return "RECOVERY#_#_";

            throw new ArgumentException("Unknown string associated with this message flag: " + flag.ToString());
        }

        public static MessageFlagSequeue GetFlag(string msg)
        {
            if (isFlag(msg, MessageFlagSequeue.BEGIN)) return MessageFlagSequeue.BEGIN;
            if (isFlag(msg, MessageFlagSequeue.END)) return MessageFlagSequeue.END;
            if (isFlag(msg, MessageFlagSequeue.END_RECOVERY)) return MessageFlagSequeue.END_RECOVERY;
            
            if(!isValidFlag(msg))
                throw new InvalidOperationException("Unknown flag is in used");
            return MessageFlagSequeue.NULL;
        }

        private static bool isFlag(string msg, MessageFlagSequeue flag)
        {
            if (GetFlag(flag).Equals(msg, StringComparison.Ordinal))
                return true;
            else
                return false;
        }

        private static bool isValidFlag(string flag)
        {
            if (isFlag(flag, MessageFlagSequeue.BEGIN) ||
                isFlag(flag, MessageFlagSequeue.END) ||
                isFlag(flag, MessageFlagSequeue.END_RECOVERY))
                return true;
            return false;
        }
    }

    //// take a message from price server and push to vdata appropritely
    //public class VDataMessageProtocol
    //{
    //    CommunicationDataQueue _queue;
    //    VdataMessageSender _sender;
    //    VdataFlagChecker _flagChecker;

    //    static EventWaitHandle _firstTimeFlag = new AutoResetEvent(true);
    //    static EventWaitHandle _transactionFlag = new AutoResetEvent(false);

    //    // store all the threads
    //    Dictionary<string, Thread> _threadDictionary;

    //    public VDataMessageProtocol() { }

    //    /// <summary>
    //    /// Send 1st time and enclose the message inside a BEGIN END
    //    /// </summary>
    //    protected void SendFirstTime(IDictionary<string, PriceLibrary.PriceService.StockBase> baseprices, IDictionary<string, PriceLibrary.PriceService.StockBase> top3Prices)
    //    {
    //        SendFlag(MessageFlagSequeue.BEGIN);
            
    //        // send all 



    //        SendFlag(MessageFlagSequeue.END);           
    //    }

    //    /// <summary>
    //    /// after 1st time, send Transactions end with RECOVERY
    //    /// </summary>
    //    protected void SendTransactions() {
    //        _firstTimeFlag.WaitOne();            
    //        // send all transactions
    //        SendFlag(MessageFlagSequeue.END_RECOVERY);
    //        // release transaction flag
    //        _transactionFlag.Set();
    //    }


    //    protected void SendFlag(MessageFlagSequeue flag)
    //    {
    //        // _flagChecker.CheckFlag(VDataFlag.GetFlag(flag));
                 
    //    }

    //    //protected void SendObject(PriceLibrary.ChartService.Transaction transaction)
    //    //{
    //    //    _sender.SendTransaction(transaction, _queue);
    //    //}
    //}
}
